package com.xyht.medicine_management_system.modules.coupon.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xyht.medicine_management_system.common.commonReturn.CommonCodeEnum;
import com.xyht.medicine_management_system.common.commonReturn.CommonResult;
import com.xyht.medicine_management_system.common.commonReturn.ResponseResult;
import com.xyht.medicine_management_system.modules.coupon.constant.CouponConstant;
import com.xyht.medicine_management_system.modules.coupon.constant.UserCouponRelationConstant;
import com.xyht.medicine_management_system.modules.coupon.entity.MmsCoupon;
import com.xyht.medicine_management_system.modules.coupon.entity.MmsUserCouponRelation;
import com.xyht.medicine_management_system.modules.coupon.entity.req.MmsCouponReq;
import com.xyht.medicine_management_system.modules.coupon.entity.resp.MmsCouponResp;
import com.xyht.medicine_management_system.modules.coupon.mapper.MmsCouponMapper;
import com.xyht.medicine_management_system.modules.coupon.mapper.MmsUserCouponRelationMapper;
import com.xyht.medicine_management_system.modules.coupon.service.MmsCouponService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import static com.xyht.medicine_management_system.common.util.ParamCheckUtil.isNullOrEmpty;

/**
 * <p>
 * 优惠劵表 服务实现类
 * </p>
 *
 * @author XYHT
 * @since 2023-11-29
 */
@Service
public class MmsCouponServiceImpl extends ServiceImpl<MmsCouponMapper, MmsCoupon> implements MmsCouponService {
    @Resource
    private MmsCouponMapper mmsCouponMapper;
    @Resource
    private MmsUserCouponRelationMapper mmsUserCouponRelationMapper;

    @Override
    public ResponseResult addCoupon(MmsCouponReq couponReq, String userId) {
        if (isNullOrEmpty(couponReq.getName(), couponReq.getType(), couponReq.getStartDate(), couponReq.getEndDate())) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }
        if (couponReq.getType() != CouponConstant.COUPON_TYPE_FULL_REDUCTION && couponReq.getType() != CouponConstant.COUPON_TYPE_NO_THRESHOLD) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }
        //满减优惠券必须设置 满减额度
        if (couponReq.getType() == CouponConstant.COUPON_TYPE_FULL_REDUCTION) {
            if (isNullOrEmpty(couponReq.getFullReduction(), couponReq.getDiscountAmount())) {
                return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
            }
        } else {//无门槛优惠券必须设置 优惠金额
            if (isNullOrEmpty(couponReq.getDiscountAmount())) {
                return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
            }
        }

        //添加优惠券
        MmsCoupon coupon = new MmsCoupon();
        coupon.setCreator(userId);
        BeanUtils.copyProperties(couponReq, coupon);
        //设置没人可领取次数
        if (isNullOrEmpty(couponReq.getUsageLimit())) {
            coupon.setUsageLimit(0);
        }
        this.save(coupon);

        return CommonResult.success();
    }

    @Override
    public ResponseResult delCoupon(MmsCouponReq couponReq) {
        if (isNullOrEmpty(couponReq.getId())) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }

        MmsCoupon coupon = mmsCouponMapper.selectById(couponReq.getId());
        if (isNullOrEmpty(coupon)) {
            return CommonResult.failed(CommonCodeEnum.COUPON_NOT_EXIST);
        }

        mmsCouponMapper.deleteById(couponReq.getId());

        return CommonResult.success();
    }

    @Override
    public ResponseResult updateCoupon(MmsCouponReq couponReq) {
        if (isNullOrEmpty(couponReq.getId())) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }

        MmsCoupon coupon = mmsCouponMapper.selectById(couponReq.getId());
        if (isNullOrEmpty(coupon)) {
            return CommonResult.failed(CommonCodeEnum.COUPON_NOT_EXIST);
        }

        if (couponReq.getType() != CouponConstant.COUPON_TYPE_FULL_REDUCTION && couponReq.getType() != CouponConstant.COUPON_TYPE_NO_THRESHOLD) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }
        //满减优惠券必须设置 满减额度
        if (couponReq.getType() == CouponConstant.COUPON_TYPE_FULL_REDUCTION) {
            if (isNullOrEmpty(couponReq.getFullReduction(), couponReq.getDiscountAmount())) {
                return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
            }
        } else {//无门槛优惠券必须设置 优惠金额
            if (isNullOrEmpty(couponReq.getDiscountAmount())) {
                return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
            }
        }

        BeanUtils.copyProperties(couponReq, coupon);

        mmsCouponMapper.updateById(coupon);

        return CommonResult.success();
    }

    @Override
    public ResponseResult listCoupon(Integer pageNum, Integer pageSize, String searchStr) {
        LambdaQueryWrapper<MmsCoupon> queryWrapper = new LambdaQueryWrapper<MmsCoupon>().orderByDesc(MmsCoupon::getCreateTime);
        if (!isNullOrEmpty(searchStr)) {
            StringUtils.deleteWhitespace(searchStr);
            queryWrapper.like(MmsCoupon::getName, searchStr).or()
                    .like(MmsCoupon::getNote, searchStr);
        }

        Page<MmsCoupon> page = new Page<>(pageNum, pageSize);
        mmsCouponMapper.selectPage(page, queryWrapper);

        List<MmsCouponResp> couponRespList = page.getRecords().stream().map(coupon -> {
            MmsCouponResp couponResp = new MmsCouponResp();
            BeanUtils.copyProperties(coupon, couponResp);
            return couponResp;
        }).collect(Collectors.toList());

        return CommonResult.success(couponRespList, (int) page.getTotal());
    }

    @Override
    public ResponseResult couponDetail(String couponId) {
        if (isNullOrEmpty(couponId)) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }

        MmsCoupon coupon = mmsCouponMapper.selectById(couponId);
        if (isNullOrEmpty(coupon)) {
            return CommonResult.failed(CommonCodeEnum.COUPON_NOT_EXIST);
        }

        MmsCouponResp couponResp = new MmsCouponResp();
        BeanUtils.copyProperties(coupon, couponResp);

        return CommonResult.success(couponResp);
    }

    @Override
    public ResponseResult userCanGetList(Integer pageNum, Integer pageSize, String searchStr, String userId) {
        Date nowDate = new Date();
        LambdaQueryWrapper<MmsCoupon> queryWrapper = new LambdaQueryWrapper<MmsCoupon>()
                .eq(MmsCoupon::getStatus, CouponConstant.COUPON_STATUS_AVAILABLE) // 可用
                .le(MmsCoupon::getStartDate, nowDate)
                .ge(MmsCoupon::getEndDate, nowDate)
                .orderByDesc(MmsCoupon::getCreateTime);

        if (!isNullOrEmpty(searchStr)) {
            StringUtils.deleteWhitespace(searchStr);
            queryWrapper.and(i -> i.like(MmsCoupon::getName, searchStr).or()
                    .like(MmsCoupon::getNote, searchStr));
        }

        Page<MmsCoupon> page = new Page<>(pageNum, pageSize);
        this.page(page, queryWrapper);
        List<MmsCouponResp> collect = page.getRecords().stream().map(coupon -> {
            MmsCouponResp couponResp = new MmsCouponResp();
            BeanUtils.copyProperties(coupon, couponResp);

            // 用户是否可领取
            boolean userCanGet = true;
            if (coupon.getReceiveLimit() != null) {
                if (coupon.getReceiveLimit() <= 0) { // 优惠券总量小于等于0
                    userCanGet = false;
                }
            }

            // 用户拥有数已达上限
            Integer userOwnedCount = mmsUserCouponRelationMapper.selectCount(new LambdaQueryWrapper<MmsUserCouponRelation>()
                    .eq(MmsUserCouponRelation::getCouponId, coupon.getId()));
            if (userOwnedCount >= coupon.getUsageLimit()) {
                userCanGet = false;
            }

            couponResp.setUserCanGet(userCanGet);

            return couponResp;
        }).collect(Collectors.toList());


        return CommonResult.success(collect, (int) page.getTotal());
    }

}
